#include "nnslitevector.h"

/** nnsliteVector  */
NNSLITE_RET nnsliteVectorInit(nnsliteVector* v, u32 elemsize)
{
	v->capacity = 16;
	v->elemsize = elemsize;
	v->buf = (u8*)malloc(v->elemsize*v->capacity);
	if (v->buf == NULL)
		return NNSLITE_RET_ERR_ALLOCATE_MEM;
	v->size = 0;
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorFree(nnsliteVector* v)
{
	if (v->buf != NULL)
		free(v->buf);
	v->buf = NULL;
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorClear(nnsliteVector* v)
{
	if (NNSLITE_RET_OK != nnsliteVectorFree(v))
		return NNSLITE_RET_ERR;
	if (NNSLITE_RET_OK != nnsliteVectorInit(v, v->elemsize))
		return NNSLITE_RET_ERR;
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorGet(nnsliteVector* v, u32 index, void* ptr)
{
	memcpy(ptr,v->buf+index*v->elemsize, v->elemsize);
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorPushback(nnsliteVector* v, void* ptr)
{
	if (v->capacity == v->size)
	{
		u32 newcapacity = v->capacity * 2;
		u8* newbuf = (u8*)malloc(v->elemsize*newcapacity);
		if (newbuf == NULL)
			return NNSLITE_RET_ERR_ALLOCATE_MEM;
		memcpy(newbuf, v->buf, v->elemsize*v->capacity);
		free(v->buf);
		v->buf = newbuf;
		v->capacity = newcapacity;
	}
	memcpy(v->buf+(v->size*v->elemsize), ptr, v->elemsize);
	v->size++;
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorDelete(nnsliteVector* v, u32 index)
{
	if (v->size <= index)
		return NNSLITE_RET_ERR_INDEX_OUTOFBOUND;
	memmove(v->buf+v->elemsize*index, v->buf+v->elemsize*(index+1), v->elemsize*(v->size-index-1));
	v->size--;
	return NNSLITE_RET_OK;
}

NNSLITE_RET nnsliteVectorReplace(nnsliteVector* v, u32 index, void* ptr)
{
	memcpy(v->buf+index*v->elemsize, ptr, v->elemsize);
	return NNSLITE_RET_OK;
}
